/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */

#ifndef SQUAREABSTRACT_H_
#define SQUAREABSTRACT_H_

#include "../EnumAbstract.h"

template<template<class, class, typename> class Square, class F, class R, typename Int>
class SquareAbstract : public EnumAbstract<Square<File, Rank, Int>, Int> {
public:
	typedef F File;
	typedef R Rank;
public:
	static const Int COUNT = 64;

#	define _(_F,_R)\
		static const Square<F,R,Int> _F##_R() {\
			return Square<F,R,Int>(File::_F(), Rank::R##_R());\
		}

		_(A,1) _(A,2) _(A,3) _(A,4) _(A,5) _(A,6) _(A,7) _(A,8)
		_(B,1) _(B,2) _(B,3) _(B,4) _(B,5) _(B,6) _(B,7) _(B,8)
		_(C,1) _(C,2) _(C,3) _(C,4) _(C,5) _(C,6) _(C,7) _(C,8)
		_(D,1) _(D,2) _(D,3) _(D,4) _(D,5) _(D,6) _(D,7) _(D,8)
		_(E,1) _(E,2) _(E,3) _(E,4) _(E,5) _(E,6) _(E,7) _(E,8)
		_(F,1) _(F,2) _(F,3) _(F,4) _(F,5) _(F,6) _(F,7) _(F,8)
		_(G,1) _(G,2) _(G,3) _(G,4) _(G,5) _(G,6) _(G,7) _(G,8)
		_(H,1) _(H,2) _(H,3) _(H,4) _(H,5) _(H,6) _(H,7) _(H,8)
#	undef _

public:
	static const Square<F,R,Int> BEGIN() { return Square<F,R,Int>::A1(); }
	static const Square<F,R,Int> RBEGIN() { return Square<F,R,Int>::H8(); }
public:
	void fromFileAndRank(const File f, const Rank r) {
		this->me().setFile(f);
		this->me().setRank(r);
	}

	std::string toStr() const {
		if ( this->me_c().isNil() )
			return "-";
		else
			return this->me_c().file().toStr() + this->me_c().rank().toStr();
	}

	void fromStr(const std::string str) {
		if ( "-" == str ) {
			this->me() = Square<F,R,Int>::NIL();
			return;
		}

		File f = File(str.substr(0,1));
		Rank r = Rank(str.substr(1));
		this->me().fromFileAndRank(f,r);
	}

};

#endif /* SQUAREABSTRACT_H_ */

